using ObjFileLoader.Data.DataStore;
using ObjFileLoader.TypeParsers.Interfaces;
using System.Collections.Generic;
using System.IO;

namespace ObjFileLoader.Loaders
{
    public class ObjLoader : LoaderBase, IObjLoader
    {
        private string filePath;
        private readonly IDataStore _dataStore;

        private readonly List<ITypeParser> _typeParsers = new List<ITypeParser>();

        private readonly List<string> _unrecognizedLines = new List<string>();

        public ObjLoader(IDataStore dataStore, IFaceParser faceParser, IGroupParser groupParser, INormalParser normalParser, ITextureParser textureParser, IVertexParser vertexParser, IMaterialLibraryParser materialLibraryParser, IUseMaterialParser useMaterialParser)
        {
            _dataStore = dataStore;
            SetupTypeParsers(vertexParser, faceParser, normalParser, textureParser, groupParser, materialLibraryParser, useMaterialParser);
        }

        private void SetupTypeParsers(params ITypeParser[] parsers)
        {
            foreach (ITypeParser item in parsers)
            {
                _typeParsers.Add(item);
            }
        }

        protected override void ParseLine(string keyword, string data)
        {
            foreach (ITypeParser typeParser in _typeParsers)
            {
                if (typeParser.CanParse(keyword))
                {
                    if (keyword == "mtllib")
                        data = filePath.Substring(0, filePath.LastIndexOf("\\") + 1) + data;
                    typeParser.Parse(data);
                    return;
                }
            }
            _unrecognizedLines.Add(keyword + " " + data);
        }

        public LoadResult Load(Stream lineStream)
        {
            StartLoad(lineStream);
            return CreateResult();
        }
        public LoadResult Load(string filePath)
        {
            this.filePath = filePath;
            var stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
            return Load(stream);
        }

        private LoadResult CreateResult()
        {
            return new LoadResult
            {
                Vertices = _dataStore.Vertices,
                Textures = _dataStore.Textures,
                Normals = _dataStore.Normals,
                Groups = _dataStore.Groups,
                Materials = _dataStore.Materials
            };
        }
    }
}
